#include <bits/stdc++.h>
using namespace std;
int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
int earliest[510][510]; // 先记录每一块格子最早受影响的时间
int step[510][510];     // 最少步数
const int SIZE = 500;

struct Point {
  int x;
  int y;
  int step; // 坐标，步数
};

queue<Point> Q;

// 宽搜
void bfs() {
//   step[0][0] = 0;
  Q.push({0, 1, 1});
  Q.push({1, 0, 1});
  step[0][1] = 1;
  step[1][0] = 1;
  while (!Q.empty()) {
    Point h = Q.front();
    Q.pop();
    if (earliest[h.x][h.y] > 1001) { // 因为初始化是1002，所以这里代表安全
      cout << h.step << endl; // 输出步数
      return;
    }
    for (int i = 0; i < 4; i++) {
      int tx = h.x + dir[i][0];
      int ty = h.y + dir[i][1];
      if (tx >= 0 && ty >= 0 && tx < SIZE && ty < SIZE && step[tx][ty] == -1 &&
          h.step + 1 < earliest[tx][ty]) {
        // 判断越界并且没被搜过并且流星还没砸下来
        step[tx][ty] = h.step + 1;
        Q.push({tx, ty, h.step + 1});
      }
    }
  }
  cout << "No Solution" << endl; // 不幸，被砸死了
}
int main() {
  int n;
  scanf("%d", &n);
  for (int i = 0; i < SIZE; i++) {
    for (int j = 0; j < SIZE; j++) {
      earliest[i][j] = 1002; // 初始化
    }
  }
  memset(step, -1, sizeof(step));

  for (int i = 1; i <= n; i++) {
    int x, y, t;
    scanf("%d%d%d", &t, &x, &y);
    earliest[x][y] = min(earliest[x][y], t); // 最先砸下来的
    for (int j = 0; j < 4; j++) {            // 四个方向
      int tx = x + dir[j][0];
      int ty = y + dir[j][1];
      if (tx >= 0 && ty >= 0) // 判断越界
        earliest[tx][ty] = min(earliest[tx][ty], t + 1);
    }
  }
  bfs();
  return 0;
}
